package com.huishu.coupon.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huishu.commons.config.cache.RedisUtil;
import com.huishu.commons.constant.RedisKeyPrefix;
import com.huishu.commons.exception.BaseException;
import com.huishu.commons.exception.NotFoundException;
import com.huishu.commons.pojo.Result;
import com.huishu.commons.pojo.dto.FindAvailableCouponDTO;
import com.huishu.commons.pojo.dto.SendRepurchaseDTO;
import com.huishu.commons.pojo.vo.CouponVO;
import com.huishu.commons.utlis.BeanUtils;
import com.huishu.commons.utlis.DateUtils;
import com.huishu.coupon.mapper.CouponHistoryMapper;
import com.huishu.coupon.mapper.CouponMapper;
import com.huishu.coupon.mapper.CouponProductCategoryRelationMapper;
import com.huishu.coupon.mapper.CouponProductRelationMapper;
import com.huishu.coupon.pojo.dto.CouponCreateDTO;
import com.huishu.coupon.pojo.dto.CouponPageDTO;
import com.huishu.coupon.pojo.dto.CouponUpdateDTO;
import com.huishu.coupon.pojo.model.CouponDO;
import com.huishu.coupon.pojo.model.CouponHistoryDO;
import com.huishu.coupon.pojo.model.CouponProductCategoryRelationDO;
import com.huishu.coupon.pojo.model.CouponProductRelationDO;
import com.huishu.coupon.pojo.vo.CouponPageVO;
import com.huishu.coupon.service.CouponHistoryService;
import com.huishu.coupon.service.CouponService;
import com.huishu.coupon.utils.AssistantContext;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator@ljj
 * @since 2023-04-10
 */
@Slf4j
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponDO> implements CouponService {

    @Autowired
    @Qualifier("threadPoolTaskExecutor")
    private Executor executor;

    @Autowired
    private CouponProductRelationMapper couponProductRelationMapper;

    @Autowired
    private CouponProductCategoryRelationMapper couponProductCategoryRelationMapper;

    @Autowired
    private CouponHistoryMapper couponHistoryMapper;

    @Autowired
    private CouponHistoryService couponHistoryService;

    @Autowired
    private RedisUtil redisUtil;
/*
    @Override
    public Result<List<CouponVO>> findCouponByProductId(Long productId) {
        LambdaQueryWrapper<CouponProductRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductRelationDO.class)
                .eq(CouponProductRelationDO::getProductId, productId);
        List<CouponProductRelationDO> couponProductRelations = couponProductRelationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponProductRelations)) {
            return Result.success();
        }
        List<Long> couponIds = couponProductRelations.stream().map(CouponProductRelationDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .ge(CouponDO::getStartDate,new Date())
                .le(CouponDO::getEnableDate,new Date())
                .in(CouponDO::getId,couponIds);
        List<CouponDO> coupons = this.baseMapper.selectList(couponQueryWrapper);
        if (CollectionUtils.isEmpty(coupons)) {
            log.info("查询优惠卷为空:" + JSON.toJSONString(coupons));
            return Result.success();
        }
        return Result.success(coupons.stream().map(couponDO -> BeanUtils.copyProperties(couponDO, CouponVO.class)).collect(Collectors.toList()));
    }

    @Override
    public Result<List<CouponVO>> findCouponByProductCategoryId(Long productCategoryId) {
        LambdaQueryWrapper<CouponProductCategoryRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductCategoryRelationDO.class)
                .eq(CouponProductCategoryRelationDO::getProductCategoryId, productCategoryId);
        List<CouponProductCategoryRelationDO> couponProductCategoryRelations = couponProductCategoryRelationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponProductCategoryRelations)) {
            return Result.success();
        }
        List<Long> couponIds = couponProductCategoryRelations.stream().map(CouponProductCategoryRelationDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .ge(CouponDO::getStartDate,new Date())
                .le(CouponDO::getEnableDate,new Date())
                .in(CouponDO::getId,couponIds);
        List<CouponDO> coupons = this.baseMapper.selectList(couponQueryWrapper);
        if (CollectionUtils.isEmpty(coupons)) {
            log.info("查询优惠卷为空:" + JSON.toJSONString(coupons));
            return Result.success();
        }
        return Result.success(coupons.stream().map(couponDO -> BeanUtils.copyProperties(couponDO, CouponVO.class)).collect(Collectors.toList()));
    }*/

    @Override
    public Result<List<CouponVO>> findAvailableCoupon(FindAvailableCouponDTO findAvailableCouponDTO) {
        List<CouponVO> coupons = new ArrayList<>();
        try {
            //CompletableFuture<List<CouponVO>> future = CompletableFuture.supplyAsync(() -> {
            //    List<CouponVO> productCoupons = new ArrayList<>();
            //    if (CollectionUtils.isNotEmpty(findAvailableCouponDTO.getProductIds())) {
            //        List<CouponDO> productCoupon = findProductCoupon(findAvailableCouponDTO.getProductIds());
            //        if (CollectionUtils.isNotEmpty(productCoupon)) {
            //            productCoupons.addAll(productCoupon.stream()
            //                    .map(couponDO -> BeanUtils.copyProperties(couponDO, CouponVO.class)).collect(Collectors.toList()));
            //        }
            //        return productCoupons;
            //    }
            //    return productCoupons;
            //}, executor);


            //CompletableFuture<List<CouponVO>> future = CompletableFuture.supplyAsync(() -> {
            //    List<CouponVO> productCoupons = new ArrayList<>();
            //    // 查询我的优惠卷
            //    if (AssistantContext.getCurrentUid() == null) {
            //        // 未登入
            //        return productCoupons;
            //    }
            //    List<CouponDO> myCoupon = findMyCoupon(AssistantContext.getCurrentUid());
            //    if (CollectionUtils.isNotEmpty(myCoupon)) {
            //        productCoupons.addAll(myCoupon.stream()
            //                .map(couponDO -> BeanUtils.copyProperties(couponDO, CouponVO.class)).collect(Collectors.toList()));
            //    }
            //    return productCoupons;
            //}, executor);

            CompletableFuture<List<CouponVO>> future1 = CompletableFuture.supplyAsync(() -> {
                List<CouponVO> categoryCoupons = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(findAvailableCouponDTO.getProductCategoryIds())) {
                    List<CouponDO> categoryCoupon = findCategoryCoupon(findAvailableCouponDTO.getProductCategoryIds());
                    if (CollectionUtils.isNotEmpty(categoryCoupon)) {
                        categoryCoupons.addAll(categoryCoupon.stream()
                                .map(couponDO -> BeanUtils.copyProperties(couponDO, CouponVO.class)).collect(Collectors.toList()));
                    }
                    return categoryCoupons;
                }
                return categoryCoupons;
            }, executor);

            CompletableFuture<List<CouponVO>> future2 = CompletableFuture.supplyAsync(() -> {
                List<CouponVO> wholeCoupons = new ArrayList<>();
                // 查询全场优惠卷
                LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                        .le(CouponDO::getStartDate, new Date())
                        .ge(CouponDO::getEndDate, new Date())
                        .eq(CouponDO::getIsRelease, 1)
                        .eq(CouponDO::getType, 0)
                        .eq(CouponDO::getUseType, 0);
                List<CouponDO> wholeCoupon = this.baseMapper.selectList(couponQueryWrapper);
                if (CollectionUtils.isNotEmpty(wholeCoupon)) {
                    wholeCoupons.addAll(wholeCoupon.stream()
                            .map(couponDO -> BeanUtils.copyProperties(couponDO, CouponVO.class)).collect(Collectors.toList()));
                }
                return wholeCoupons;
            }, executor);


            CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2);
            allOf.get();
            coupons.addAll(future1.get());
            coupons.addAll(future2.get());
            //List<CouponVO> myCoupon = future.get();
            //if (CollectionUtils.isEmpty(myCoupon)) {
            //    coupons.addAll(future1.get());
            //    coupons.addAll(future2.get());
            //} else {
            //    // 维护已领取优惠卷
            //    List<CouponVO> categoryCoupons = future1.get();
            //    categoryCoupons = categoryCoupons.stream().map(couponVO -> {
            //        for (CouponVO vo : myCoupon) {
            //            if (vo.getId().equals(couponVO.getId())) {
            //                couponVO.setIsUse(true);
            //            }
            //        }
            //        return couponVO;
            //    }).collect(Collectors.toList());
            //    List<CouponVO> couponAll = future2.get();
            //    for (CouponVO couponVO : couponAll) {
            //        for (CouponVO vo : myCoupon) {
            //            if (vo.getId().equals(couponVO.getId())) {
            //                couponVO.setIsUse(true);
            //            }
            //        }
            //    }
            //    coupons.addAll(categoryCoupons);
            //    coupons.addAll(couponAll);
            //}
            return Result.success(coupons);
        } catch (Exception e) {
            log.error("查询优惠卷异常!");
            throw new NotFoundException("查询优惠卷异常");
        }
    }

    private List<CouponDO> findMyCoupon(Long id) {
        LambdaQueryWrapper<CouponHistoryDO> queryWrapper = Wrappers.lambdaQuery(CouponHistoryDO.class)
                .eq(CouponHistoryDO::getUseStatus, 0)
                .eq(CouponHistoryDO::getUserId, id)
                .isNull(CouponHistoryDO::getOverdueDate);
        List<CouponHistoryDO> couponHistoryDOS = couponHistoryMapper.selectList(queryWrapper);
        List<Long> couponIds = couponHistoryDOS.stream().map(CouponHistoryDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .le(CouponDO::getStartDate, new Date())
                .ge(CouponDO::getEndDate, new Date())
                .eq(CouponDO::getIsRelease, 1)
                .in(CouponDO::getId, couponIds);
        return this.baseMapper.selectList(couponQueryWrapper);
    }

    @Override
    public Result<List<CouponVO>> findCouponByUserId(Long userId, List<Long> categoryId) {
        LambdaQueryWrapper<CouponHistoryDO> queryWrapper = Wrappers.lambdaQuery(CouponHistoryDO.class)
                .eq(CouponHistoryDO::getUseStatus, 0)
                .isNull(CouponHistoryDO::getOverdueDate)
                .eq(CouponHistoryDO::getUserId, userId);
        List<CouponHistoryDO> couponHistorys = couponHistoryMapper.selectList(queryWrapper);
        List<Long> couponIds = couponHistorys.stream().map(CouponHistoryDO::getCouponId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(couponIds)) {
            return Result.success(new ArrayList<>());
        }
        List<CouponDO> userCoupons = this.baseMapper.selectBatchIds(couponIds);
        // 判断当前优惠卷在购物车中是否可用
        LambdaQueryWrapper<CouponProductCategoryRelationDO> queryWrapper1 = Wrappers.lambdaQuery(CouponProductCategoryRelationDO.class)
                .in(CouponProductCategoryRelationDO::getProductCategoryId, categoryId);
        List<CouponProductCategoryRelationDO> couponProductCategoryRelationDOS = couponProductCategoryRelationMapper.selectList(queryWrapper1);
        List<Long> couponIdsCategoryRelation = couponProductCategoryRelationDOS.stream().map(CouponProductCategoryRelationDO::getCouponId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(couponIdsCategoryRelation)) {
            // 说明当前购物车中没有品类给优惠卷命中
            List<CouponVO> collect = userCoupons.stream().map(couponDO -> {
                CouponVO couponVO = BeanUtils.copyProperties(couponDO, CouponVO.class);
                if (couponVO.getUseType() == 1) {
                    couponVO.setIsUse(false);
                }
                return couponVO;
            }).collect(Collectors.toList());
            return Result.success(collect);
        }
        List<CouponDO> coupons = this.list(Wrappers.lambdaQuery(CouponDO.class)
                .in(CouponDO::getId, couponIdsCategoryRelation));

        // 反之，需要判断优惠卷中命中的品类是否在购物车中
        List<CouponVO> collect = userCoupons.stream().map(couponDO -> {
            CouponVO couponVO = BeanUtils.copyProperties(couponDO, CouponVO.class);
            if (!coupons.contains(couponDO)) {
                if (couponVO.getUseType() == 1) {
                    couponVO.setIsUse(false);
                }
            }
            return couponVO;
        }).collect(Collectors.toList());
        return Result.success(collect);
    }

    @Override
    public Result findUnclaimed() {
        // 查询待领取的优惠卷
        LambdaQueryWrapper<CouponHistoryDO> queryWrapper = Wrappers.lambdaQuery(CouponHistoryDO.class)
                .eq(CouponHistoryDO::getUserId, AssistantContext.getCurrentUid());
        List<CouponHistoryDO> couponHistorys = couponHistoryMapper.selectList(queryWrapper);
        List<Long> couponIds = couponHistorys.stream().map(CouponHistoryDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .le(CouponDO::getStartDate, new Date())
                .ge(CouponDO::getEndDate, new Date())
                .notIn(CouponDO::getId, couponIds);
        return Result.success(this.list(couponQueryWrapper));
    }

    @Override
    public Result findRepurchaseCoupon() {
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .eq(CouponDO::getType, 2)
                .eq(CouponDO::getIsRelease, 1);
        return Result.success(this.list(couponQueryWrapper));
    }

    @Override
    public Result pageList(CouponPageDTO couponPageDTO) {
        Page<CouponPageVO> page = new Page<>(couponPageDTO.getCurrPage(), couponPageDTO.getPageSize());
        return Result.success(this.baseMapper.pageList(page, couponPageDTO));
    }

    @Override
    public Result findById(Long id) {
        CouponDO couponDO = this.getById(id);
        com.huishu.coupon.pojo.vo.CouponVO couponVO = BeanUtils.copyProperties(couponDO, com.huishu.coupon.pojo.vo.CouponVO.class);
        if (couponDO.getUseType() == 1) {
            LambdaQueryWrapper<CouponProductCategoryRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductCategoryRelationDO.class)
                    .eq(CouponProductCategoryRelationDO::getCouponId, id);
            CouponProductCategoryRelationDO couponProductCategoryRelationDO = couponProductCategoryRelationMapper.selectOne(queryWrapper);
            couponVO.setCategoryId(couponProductCategoryRelationDO.getProductCategoryId());
        }
        return Result.success(couponVO);
    }

    @Transactional
    @Override
    public Result create(CouponCreateDTO couponCreateDTO) {
        CouponDO couponDO = BeanUtils.copyProperties(couponCreateDTO, CouponDO.class);
        boolean save = this.save(couponDO);
        if (!save) {
            throw new BaseException("添加失败");
        }
        if (couponCreateDTO.getUseType() == 1 && couponCreateDTO.getCategoryId() != null) {
            // 绑定品类
            couponBindCategory(couponDO, couponCreateDTO.getCategoryId());
        }
        return Result.success();
    }

    @Transactional
    @Override
    public Result modify(CouponUpdateDTO couponUpdateDTO) {
        CouponDO couponDO = BeanUtils.copyProperties(couponUpdateDTO, CouponDO.class);
        boolean b = this.updateById(couponDO);
        if (!b) {
            throw new BaseException("修改失败");
        }
        LambdaQueryWrapper<CouponProductCategoryRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductCategoryRelationDO.class)
                .eq(CouponProductCategoryRelationDO::getCouponId, couponDO.getId());
        couponProductCategoryRelationMapper.delete(queryWrapper);
        if (couponUpdateDTO.getUseType() == 1 && couponUpdateDTO.getCategoryId() != null) {
            // 绑定品类
            couponBindCategory(couponDO, couponUpdateDTO.getCategoryId());
        }
        // 判断是否是在有效期内
        if (DateUtils.compareGt(couponDO.getEndDate(), new Date())) {
            LambdaUpdateWrapper<CouponHistoryDO> uw = Wrappers.lambdaUpdate(CouponHistoryDO.class)
                    .set(CouponHistoryDO::getUseStatus, 0)
                    .eq(CouponHistoryDO::getCouponId, couponDO.getId())
                    .eq(CouponHistoryDO::getUseStatus, 2);
            couponHistoryMapper.update(null, uw);
        }
        //if (!couponUpdateDTO.getIsRelease()) {
        //    // 禁用优惠卷
        //    LambdaUpdateWrapper<CouponHistoryDO> uw = Wrappers.lambdaUpdate(CouponHistoryDO.class)
        //            .set(CouponHistoryDO::getUseStatus, 3)
        //            .eq(CouponHistoryDO::getCouponId, couponDO.getId());
        //    couponHistoryMapper.update(null, uw);
        //} else {
        //    // 判断是否是在有效期内
        //    if (DateUtils.compareGt(couponDO.getEndDate(), new Date())) {
        //        LambdaUpdateWrapper<CouponHistoryDO> uw = Wrappers.lambdaUpdate(CouponHistoryDO.class)
        //                .set(CouponHistoryDO::getUseStatus, 0)
        //                .eq(CouponHistoryDO::getCouponId, couponDO.getId())
        //                .eq(CouponHistoryDO::getUseStatus, 3);
        //        couponHistoryMapper.update(null, uw);
        //    } else {
        //        LambdaUpdateWrapper<CouponHistoryDO> uw = Wrappers.lambdaUpdate(CouponHistoryDO.class)
        //                .set(CouponHistoryDO::getUseStatus, 2)
        //                .eq(CouponHistoryDO::getCouponId, couponDO.getId())
        //                .eq(CouponHistoryDO::getUseStatus, 3);
        //        couponHistoryMapper.update(null, uw);
        //    }
        //}
        return Result.success();
    }

    @Transactional
    @Override
    public Result disableOrOpen(CouponUpdateDTO couponUpdateDTO) {
        boolean update = this.update(Wrappers.lambdaUpdate(CouponDO.class)
                .set(CouponDO::getIsRelease, couponUpdateDTO.getIsRelease())
                .eq(CouponDO::getId, couponUpdateDTO.getId()));
        if (!update) {
            throw new BaseException("修改失败");
        }
        //if (!couponUpdateDTO.getIsRelease()) {
        //    // 禁用优惠卷
        //    LambdaUpdateWrapper<CouponHistoryDO> uw = Wrappers.lambdaUpdate(CouponHistoryDO.class)
        //            .set(CouponHistoryDO::getUseStatus, 3)
        //            .eq(CouponHistoryDO::getCouponId, couponUpdateDTO.getId());
        //    couponHistoryMapper.update(null, uw);
        //} else {
        //    LambdaUpdateWrapper<CouponHistoryDO> uw = Wrappers.lambdaUpdate(CouponHistoryDO.class)
        //            .set(CouponHistoryDO::getUseStatus, 0)
        //            .eq(CouponHistoryDO::getCouponId, couponUpdateDTO.getId())
        //            .eq(CouponHistoryDO::getUseStatus, 3);
        //    couponHistoryMapper.update(null, uw);
        //}
        return Result.success();
    }

    @Override
    public Result sendRepurchase(SendRepurchaseDTO sendRepurchaseDTO) {
        LambdaQueryWrapper<CouponProductRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductRelationDO.class)
                .in(CouponProductRelationDO::getProductId, sendRepurchaseDTO.getProductIds());
        List<CouponProductRelationDO> couponProductRelations = couponProductRelationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponProductRelations)) {
            return Result.success();
        }
        List<Long> couponIds = couponProductRelations.stream().map(CouponProductRelationDO::getCouponId).collect(Collectors.toList());
        List<CouponDO> couponDOS = this.listByIds(couponIds);
        List<CouponHistoryDO> couponHistoryDOS = new ArrayList<>();
        for (CouponDO couponDO : couponDOS) {
            if (couponDO.getIsRelease() && !couponDO.getIsExpire()) {
                CouponHistoryDO couponHistoryDO = new CouponHistoryDO();
                couponHistoryDO.setCouponId(couponDO.getId());
                couponHistoryDO.setUseStatus(0);
                couponHistoryDO.setUserId(sendRepurchaseDTO.getUserId());
                couponHistoryDO.setGetType(0);
                // 计算过期时间
                couponHistoryDO.setOverdueDate(DateUtils.plusDay(new Date(), couponDO.getSpecialValidity()));
                couponHistoryDOS.add(couponHistoryDO);
            }
        }
        if (CollectionUtils.isEmpty(couponHistoryDOS)) {
            return Result.success();
        }
        boolean b = couponHistoryService.saveBatch(couponHistoryDOS);
        if (!b) {
            throw new BaseException("发放复购卷失败!!");
        }
        return Result.success();
        //LambdaQueryWrapper<CouponDO> queryWrapper = Wrappers.lambdaQuery(CouponDO.class)
        //        .eq(CouponDO::getType, 2)
        //        .eq(CouponDO::getIsRelease, 1);
        //List<CouponDO> coupons = this.list(queryWrapper);
        //if (CollectionUtils.isEmpty(coupons)) {
        //    return Result.success();
        //}
        //// 根据消费金额判断可以发放的复购卷
        //coupons = coupons.stream().sorted(Comparator.comparing(CouponDO::getMinPoint)).collect(Collectors.toList());
        //List<CouponDO> collect = coupons.stream()
        //        .filter(couponDO -> couponDO.getMinPoint().compareTo(sendRepurchaseDTO.getPayAmount()) > -1)
        //        .collect(Collectors.toList());
        //if (CollectionUtils.isEmpty(collect)) {
        //    return Result.success();
        //}
        //List<CouponHistoryDO> couponHistorys = collect.stream().map(couponDO -> {
        //    CouponHistoryDO couponHistoryDO = new CouponHistoryDO();
        //    couponHistoryDO.setCouponId(couponDO.getId());
        //    couponHistoryDO.setUseStatus(0);
        //    couponHistoryDO.setUserId(sendRepurchaseDTO.getUserId());
        //    couponHistoryDO.setGetType(0);
        //    // 计算过期时间
        //    couponHistoryDO.setOverdueDate(DateUtils.plusDay(new Date(), couponDO.getSpecialValidity()));
        //    return couponHistoryDO;
        //}).collect(Collectors.toList());
        //boolean b = couponHistoryService.saveBatch(couponHistorys);
        //if (!b) {
        //    throw new BaseException("发放复购卷失败!!");
        //}
        //List<Long> couponHistoryIds = couponHistorys.stream().map(CouponHistoryDO::getId).collect(Collectors.toList());
        //redisUtil.set(RedisKeyPrefix.FIRST_ORDER_COUPON + sendRepurchaseDTO.getUserId(), JSON.toJSONString(couponHistoryIds));
    }


    @Override
    public Result<List<CouponVO>> findRepurchaseByUserId(Long userId, List<Long> categoryId) {
        LambdaQueryWrapper<CouponHistoryDO> queryWrapper = Wrappers.lambdaQuery(CouponHistoryDO.class)
                .eq(CouponHistoryDO::getUserId, userId)
                .eq(CouponHistoryDO::getUseStatus, 0)
                .gt(CouponHistoryDO::getOverdueDate, new Date());
        List<CouponHistoryDO> couponHistorys = couponHistoryMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponHistorys)) {
            return Result.success();
        }
        Map<Long, List<CouponHistoryDO>> couponHistoryMaps = couponHistorys.stream().collect(Collectors.groupingBy(CouponHistoryDO::getCouponId));
        List<Long> couponIds = couponHistorys.stream().map(CouponHistoryDO::getCouponId).collect(Collectors.toList());
        List<CouponDO> couponsRepurchase = this.list(Wrappers.lambdaQuery(CouponDO.class)
                .in(CouponDO::getId, couponIds));
        if(CollectionUtils.isNotEmpty(couponsRepurchase)){
            for (CouponDO coupon : couponsRepurchase) {
                if (coupon.getType() == 2) {
                    // 处理复购卷时间
                    coupon.setEndDate(couponHistoryMaps.get(coupon.getId()).get(0).getOverdueDate());
                }
            }
        }
        // 判断当前优惠卷在购物车中是否可用
        LambdaQueryWrapper<CouponProductCategoryRelationDO> queryWrapper1 = Wrappers.lambdaQuery(CouponProductCategoryRelationDO.class)
                .in(CouponProductCategoryRelationDO::getProductCategoryId, categoryId);
        List<CouponProductCategoryRelationDO> couponProductCategoryRelationDOS = couponProductCategoryRelationMapper.selectList(queryWrapper1);
        List<Long> couponIdsCategoryRelation = couponProductCategoryRelationDOS.stream().map(CouponProductCategoryRelationDO::getCouponId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(couponIdsCategoryRelation)) {
            // 说明当前购物车中没有品类给优惠卷命中
            List<CouponVO> collect = couponsRepurchase.stream().map(couponDO -> {
                CouponVO couponVO = BeanUtils.copyProperties(couponDO, CouponVO.class);
                if (couponVO.getUseType() == 1) {
                    couponVO.setIsUse(false);
                }
                return couponVO;
            }).collect(Collectors.toList());
            return Result.success(collect);
        }
        List<CouponDO> coupons = this.list(Wrappers.lambdaQuery(CouponDO.class)
                .in(CouponDO::getId, couponIdsCategoryRelation));

        // 反之，需要判断复购卷中命中的品类是否在购物车中
        List<CouponVO> collect = couponsRepurchase.stream().map(couponDO -> {
            CouponVO couponVO = BeanUtils.copyProperties(couponDO, CouponVO.class);
            if (!coupons.contains(couponDO)) {
                if (couponVO.getUseType() == 1) {
                    couponVO.setIsUse(false);
                }
            }
            return couponVO;
        }).collect(Collectors.toList());
        return Result.success(collect);
    }

    @Override
    public Result deleteRepurchase(Long userId) {
        String value = redisUtil.getString(RedisKeyPrefix.FIRST_ORDER_COUPON + userId);
        List<Long> couponHistoryIds = JSONArray.parseArray(value, Long.class);
        log.info("couponHistoryIds:{}", value);
        int i = couponHistoryMapper.deleteBatchIds(couponHistoryIds);
        if (i > 0) {
            redisUtil.del(RedisKeyPrefix.FIRST_ORDER_COUPON + userId);
            return Result.success();
        }
        return Result.fail();
    }

    @Override
    public Result findRepurchaseCouponByProductId(Long id) {
        LambdaQueryWrapper<CouponProductRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductRelationDO.class)
                .eq(CouponProductRelationDO::getProductId, id);
        List<CouponProductRelationDO> couponProductRelations = couponProductRelationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponProductRelations)) {
            return Result.success();
        }
        List<Long> couponIds = couponProductRelations.stream().map(CouponProductRelationDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .eq(CouponDO::getType, 2)
                .eq(CouponDO::getIsRelease, 1)
                .in(CouponDO::getId, couponIds);
        return Result.success(this.list(couponQueryWrapper));
    }

    @Override
    public Result<Map<Long, Boolean>> findRepurchaseByProductIds(List<Long> ids) {
        LambdaQueryWrapper<CouponProductRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductRelationDO.class)
                .in(CouponProductRelationDO::getProductId, ids);
        List<CouponProductRelationDO> couponProductRelations = couponProductRelationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponProductRelations)) {
            return Result.success();
        }
        List<Long> couponIds = couponProductRelations.stream().map(CouponProductRelationDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .eq(CouponDO::getType, 2)
                .eq(CouponDO::getIsRelease, 1)
                .in(CouponDO::getId, couponIds);
        List<CouponDO> list = this.list(couponQueryWrapper);
        Map<Long, CouponDO> couponMap = list.parallelStream()
                .collect(Collectors.toMap(CouponDO::getId, c -> c));
        Map<Long, Boolean> map = new HashMap<>();
        for (CouponProductRelationDO couponProductRelation : couponProductRelations) {
            CouponDO couponDO = couponMap.get(couponProductRelation.getCouponId());
            if (couponDO != null && !couponDO.getIsExpire()) {
                map.put(couponProductRelation.getProductId(), true);
            }
        }
        return Result.success(map);
    }

    private void couponBindCategory(CouponDO couponDO, Long categoryId) {
        CouponProductCategoryRelationDO couponProductCategoryRelationDO = new CouponProductCategoryRelationDO();
        couponProductCategoryRelationDO.setCouponId(couponDO.getId());
        couponProductCategoryRelationDO.setProductCategoryId(categoryId);
        int insert = couponProductCategoryRelationMapper.insert(couponProductCategoryRelationDO);
        if (insert <= 0) {
            throw new BaseException("优惠卷绑定品类关系失败！");
        }
    }

    private List<CouponDO> findProductCoupon(List<Long> productIds) {
        LambdaQueryWrapper<CouponProductRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductRelationDO.class)
                .in(CouponProductRelationDO::getProductId, productIds);
        List<CouponProductRelationDO> couponProductRelations = couponProductRelationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponProductRelations)) {
            return new ArrayList<>();
        }
        List<Long> couponIds = couponProductRelations.stream().map(CouponProductRelationDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .le(CouponDO::getStartDate, new Date())
                .ge(CouponDO::getEndDate, new Date())
                .in(CouponDO::getId, couponIds);
        return this.baseMapper.selectList(couponQueryWrapper);
    }

    /**
     * 查询关联品类的优惠卷
     *
     * @param productCategoryIds
     * @return
     */
    private List<CouponDO> findCategoryCoupon(List<Long> productCategoryIds) {
        LambdaQueryWrapper<CouponProductCategoryRelationDO> queryWrapper = Wrappers.lambdaQuery(CouponProductCategoryRelationDO.class)
                .in(CouponProductCategoryRelationDO::getProductCategoryId, productCategoryIds);
        List<CouponProductCategoryRelationDO> couponProductCategoryRelations = couponProductCategoryRelationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(couponProductCategoryRelations)) {
            return new ArrayList<>();
        }
        List<Long> couponIds = couponProductCategoryRelations.stream().map(CouponProductCategoryRelationDO::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<CouponDO> couponQueryWrapper = Wrappers.lambdaQuery(CouponDO.class)
                .le(CouponDO::getStartDate, new Date())
                .ge(CouponDO::getEndDate, new Date())
                .eq(CouponDO::getIsRelease, 1)
                .eq(CouponDO::getType, 0)
                .in(CouponDO::getId, couponIds);
        return this.baseMapper.selectList(couponQueryWrapper);
    }
}
